import os
import sys
import time

from loguru import logger
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import JSONResponse

from src.base.context import log_request_id, log_user_id, base_dir
import uuid

# 项目日志目录
log_dir = os.path.join(base_dir, "logs/")

# 项目日志配置
log_format = (
    # # 时间信息
    "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
    # 日志级别，居中对齐
    "<level>{level: ^8}</level> | "
    # 进程和线程信息
    "process[<cyan>{process}</cyan>] : thread[<cyan>{thread}]</cyan> | "
    # 请求ID
    "<cyan>req_id = {extra[request_id]}</cyan> | "
    # 用户ID
    # "<magenta>user_id = {extra[user_id]}</magenta> | "
    # 文件、函数和行号
    "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> -"
    # 日志消息
    "<level>{message}</level>"
)

# 项目服务综合日志滚动配置（每天 0 点新创建一个 log 文件）
# 错误日志 超过10 MB就自动新建文件扩充
server_log_rotation = "00:00"
error_log_rotation = "10 MB"

# 服务综合日志文件最长保留 7 天，错误日志 30 天
server_logging_retention = "7 days"
error_logging_retention = "30 days"


#

# ================== 定义contextvars


def log_filter(record):
    record["extra"] = {
        "request_id": log_request_id.get(),
        "user_id": log_user_id.get(),
    }
    return True


def configure_logger():
    # 移除默认日志处理器
    logger.remove()

    # 控制台彩色日志 (INFO级别以上)
    logger.add(sink=sys.stdout, format=log_format, level="INFO", colorize=True, backtrace=True, diagnose=True,
               filter=log_filter)
    # INFO文件日志
    logger.add(sink=log_dir + "/info_{time:YYYY-MM-DD}.log", format=log_format, level="INFO",
               rotation=server_log_rotation,
               retention=server_logging_retention, compression="zip", filter=log_filter)
    # WARN文件日志
    logger.add(sink=log_dir + "/warn_{time:YYYY-MM-DD}.log", format=log_format, level="WARNING",
               rotation=server_log_rotation,
               retention=server_logging_retention, compression="zip", filter=log_filter)
    # ERROR文件日志
    logger.add(sink=log_dir + "/error_{time:YYYY-MM-DD}.log", format=log_format, level="ERROR",
               rotation=error_log_rotation,
               retention=error_logging_retention, compression="zip", filter=log_filter)


# 获取用户 ID
async def log_depend(request: Request):
    if not hasattr(request.state, "login_user"):
        log_user_id.set("anonymous")
    else:
        login_user = request.state.login_user
        log_user_id.set(login_user.user_id)


# 中间件
class LogMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # 生成唯一请求ID
        log_request_id.set(str(uuid.uuid4()))
        # 记录请求开始
        start_time = time.time()
        # 执行请求
        response = await call_next(request)
        # 计算处理时间
        process_time = (time.time() - start_time) * 1000

        # 获取请求参数
        if request.method == "GET":
            params = dict(request.query_params)
        else:
            try:
                params = await request.json()
            except:
                params = "binary/non-json data"
        if hasattr(request.state, "login_user"):
            log_user_id.set(request.state.login_user.user_id)
        logger.info(
            "req-url：{}，req-method：{},req-params:{},resp-status:{},resp-duration：{}", request.url.path,
            request.method, params, response.status_code, process_time)
        return response
